﻿namespace starLiGHT.Sandbox.Collision
{
    #region Using Statements
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    #endregion

    public class Knight : HullObject
    {
        const float animationTime = 75f;

        Vector2 position;
        Texture2D[] texN;
        Texture2D[] texNE;
        Texture2D[] texE;
        Texture2D[] texSE;
        Texture2D[] texS;
        Texture2D[] texSW;
        Texture2D[] texW;
        Texture2D[] texNW;
        int actFrame;
        double timeAccu;
        int direction = 2;
        Boolean running;

        String[] directions = new String[] { "n", "ne", "e", "se", "s", "sw", "w", "nw" };

        public Knight(Game game, Vector2 position)
            : base(new RectangleF(position - new Vector2(32f, 56f), new Vector2(64f, 32f)).Corners)
        {
            this.position = position;

            texN = new Texture2D[12];
            texNE = new Texture2D[12];
            texE = new Texture2D[12];
            texSE = new Texture2D[12];
            texS = new Texture2D[12];
            texSW = new Texture2D[12];
            texW = new Texture2D[12];
            texNW = new Texture2D[12];
            for (int i = 0; i < 12; i++)
            {
                texN[i] = loadKnightTexture(game, "n", i);
                texNE[i] = loadKnightTexture(game, "ne", i);
                texE[i] = loadKnightTexture(game, "e", i);
                texSE[i] = loadKnightTexture(game, "se", i);
                texS[i] = loadKnightTexture(game, "s", i);
                texSW[i] = loadKnightTexture(game, "sw", i);
                texW[i] = loadKnightTexture(game, "w", i);
                texNW[i] = loadKnightTexture(game, "nw", i);
            }
        }

        Texture2D loadKnightTexture(Game game, String direction, int i)
        {
            return game.Content.Load<Texture2D>(@"FullplatedKnight/" + "running " + direction.ToLower() + "00" + i.ToString().PadLeft(2, '0'));
        }

        Texture2D GetActTexture()
        {
            switch (directions[direction])
            {
                case "n":
                    return texN[actFrame];
                case "ne":
                    return texNE[actFrame];
                case "e":
                    return texE[actFrame];
                case "se":
                    return texSE[actFrame];
                case "s":
                    return texS[actFrame];
                case "sw":
                    return texSW[actFrame];
                case "w":
                    return texW[actFrame];
                case "nw":
                    return texNW[actFrame];
            }

            throw new NotImplementedException();
        }

        public new Vector2 Position
        {
            get { return position; }
            set
            {
                position = value;
                base.Position = position - new Vector2(32f, 56f);
            }
        }

        public bool Running
        {
            get { return running; }
        }

        public Vector2 Direction
        {
            get
            {
                Vector2 dir = Vector2.Zero;

                switch (direction)
                {
                    case 0:
                        dir = new Vector2(0f, -0.5f);
                        break;
                    case 1:
                        dir = new Vector2(0.5f, -0.25f);
                        break;
                    case 2:
                        dir = new Vector2(1.0f, -0.25f);
                        break;
                    case 3:
                        dir = new Vector2(0.5f, 0.25f);
                        break;
                    case 4:
                        dir = new Vector2(0.0f, 0.5f);
                        break;
                    case 5:
                        dir = new Vector2(-0.5f, 0.25f);
                        break;
                    case 6:
                        dir = new Vector2(-1.0f, 0.0f);
                        break;
                    case 7:
                        dir = new Vector2(-0.5f, -0.25f);
                        break;
                }

                dir.Normalize();

                return dir;
            }
        }

        public void Run()
        {
            running = true;
        }

        public void Stop()
        {
            running = false;
        }

        public void TurnLeft()
        {
            direction--;
            if (direction < 0)
            {
                direction = directions.Length - 1;
            }
        }

        public void TurnRight()
        {
            direction++;
            if (direction >= directions.Length)
            {
                direction = 0;
            }
        }

        public void Update(GameTime gameTime)
        {
            if (!running)
            {
                return;
            }

            timeAccu += gameTime.ElapsedGameTime.TotalMilliseconds;

            if (timeAccu >= animationTime)
            {
                timeAccu -= animationTime;
                actFrame++;
                if (actFrame >= texE.Length)
                {
                    actFrame = 0;
                }
            }
        }

        public void Draw(SpriteBatch spriteBatch, float depth)
        {
            Texture2D tex = GetActTexture();
            spriteBatch.Draw(tex, position, null, Color.White, 0f, new Vector2(tex.CenterOrigin().X, tex.Height), 1.0f, SpriteEffects.None, depth);
        }
    }
}
